
package com.niiwoo.civet.account.service.dubbo.recharge;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dangdang.ddframe.rdb.sharding.api.HintManager;
import com.dangdang.ddframe.rdb.sharding.hint.HintManagerHolder;
import com.niiwoo.civet.account.dao.entity.*;
import com.niiwoo.civet.account.dto.common.PayChannelDTO;
import com.niiwoo.civet.account.dto.request.RechargeAccountTypeRequestDTO;
import com.niiwoo.civet.account.dto.request.RechargeDubboRequestDTO;
import com.niiwoo.civet.account.dto.request.RechargeRecordRequestDTO;
import com.niiwoo.civet.account.dto.request.UpdateRechargeRequestDTO;
import com.niiwoo.civet.account.dto.response.*;
import com.niiwoo.civet.account.enums.AccountActiveEnum;
import com.niiwoo.civet.account.enums.AccountTypeEnum;
import com.niiwoo.civet.account.service.AccountDubboService;
import com.niiwoo.civet.account.service.bankcard.BankCardDubboService;
import com.niiwoo.civet.account.service.local.AccountBalanceLocalService;
import com.niiwoo.civet.account.service.local.AccountCompanyService;
import com.niiwoo.civet.account.service.local.BankCardService;
import com.niiwoo.civet.account.service.local.BankTypeService;
import com.niiwoo.civet.account.service.local.recharge.RechargeLocalService;
import com.niiwoo.civet.account.service.local.trade.WithholdFacade;
import com.niiwoo.civet.account.service.recharge.RechargeDubboService;
import com.niiwoo.civet.base.constant.OrgConstant;
import com.niiwoo.civet.trade.constant.PlatformConstant;
import com.niiwoo.civet.trade.enums.TradeConfigEnum;
import com.niiwoo.civet.trade.service.configure.TradeConfigDubboService;
import com.niiwoo.civet.user.dto.request.SimpleOrgInfo;
import com.niiwoo.civet.user.dto.response.UserBasicInfoResponseDTO;
import com.niiwoo.civet.user.dto.response.UserIdentityInfoResponseDTO;
import com.niiwoo.civet.user.service.OrganizationDubboService;
import com.niiwoo.civet.user.service.UserBasicInfoDubboService;
import com.niiwoo.civet.user.service.UserIdentityDubboService;
import com.niiwoo.tripod.base.component.PrivacyMasks;
import com.niiwoo.tripod.lanmao.component.LanMaoDirectService;
import com.niiwoo.tripod.lanmao.component.LanMaoGatewayService;
import com.niiwoo.tripod.lanmao.component.LanMaoSequence;
import com.niiwoo.tripod.lanmao.enums.*;
import com.niiwoo.tripod.lanmao.request.QueryTransactionRequest;
import com.niiwoo.tripod.lanmao.request.RechargeRequest;
import com.niiwoo.tripod.lanmao.response.LanMaoGatewayDTO;
import com.niiwoo.tripod.lanmao.response.QueryRechargeResponse;
import com.niiwoo.tripod.provider.dto.response.PageResponseDTO;
import com.niiwoo.tripod.provider.exception.BizException;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * Created by lujing on 2017/11/8.
 */
@Service(version = "1.0.0")
public class RechargeDubboServiceImpl implements RechargeDubboService {
    private static final Logger logger = LoggerFactory.getLogger(RechargeDubboServiceImpl.class);

    @Autowired
    private RechargeLocalService rechargeLocalService;

    @Autowired
    private LanMaoGatewayService lanMaoGatewayService;

    @Autowired
    private LanMaoDirectService lanMaoDirectService;

    @Autowired
    private LanMaoSequence lanMaoSequence;

    @Autowired
    private AccountBalanceLocalService accountBalanceLocalService;

    @Autowired
    private BankCardService bankCardService;

    @Autowired
    private BankTypeService bankTypeService;

    @Autowired
    private WithholdFacade withholdFacade;

    @Autowired
    private PrivacyMasks privacyMasks;


    @Reference(version = "1.0.0")
    private BankCardDubboService bankCardDubboService;
    @Reference(version = "1.0.0")
    private TradeConfigDubboService tradeConfigDubboService;
    @Reference(version = "1.0.0")
    private UserBasicInfoDubboService userBasicInfoDubboService;
    @Reference(version = "1.0.0")
    private AccountDubboService accountDubboService;
    @Reference(version = "1.0.0")
    private UserIdentityDubboService userIdentityDubboService;
    @Autowired
    private AccountCompanyService accountCompanyService;
    @Reference(version = "1.0.0")
    private OrganizationDubboService organizationDubboService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 封装充值的请求参数
     *
     * @param rechargeDubboRequestDTO
     */
    @Override
    public RechargeResponseDTO structureParams(RechargeDubboRequestDTO rechargeDubboRequestDTO) throws ParseException {
        logger.info("封装充值的请求参数:" + JSON.toJSONString(rechargeDubboRequestDTO));
        Assert.notNull(rechargeDubboRequestDTO, "封装充值的请求参数 build structureParams rechargeDubboRequestDTO is null.");

        String requestNo = lanMaoSequence.getRequestNo();
        //默认5分钟过期
        Integer defaultExpireMin = 5;
        //查询用户账户信息
        AccountBaseResponse accountBase;
        if(OrgConstant.NIIWOO_ORG_ID.equals(rechargeDubboRequestDTO.getOrgId())){
            accountBase = accountDubboService.getNiiwooAccount(rechargeDubboRequestDTO.getUserId(), rechargeDubboRequestDTO.getRole());
        }else{
            // 如果第三方H5充值，将重定向页面缓存至redis中,缓存时间比存管页面缓存时间多2分钟
            redisTemplate.opsForValue().set(requestNo,rechargeDubboRequestDTO.getRedirectUrl(),defaultExpireMin + 3, TimeUnit.MINUTES);
            accountBase = accountDubboService.loadOrgAccount(rechargeDubboRequestDTO.getUserId(),rechargeDubboRequestDTO.getOrgId());
        }
        if(Objects.isNull(accountBase)){
            throw new BizException("ACC40006");
        }

        RechargeResponseDTO rechargeResponseDTO = null;
        if (accountBase != null) {
            //判断存管账户有没有激活
            if (AccountActiveEnum.UNACTIVATED.getValue().equals(accountBase.getImportUserActiva())) {
                throw new BizException("ACC10003");//账户未激活
            }

            //组装提交给存管的充值业务参数
            RechargeRequest rechargeRequest = new RechargeRequest();
            rechargeRequest.setPlatformUserNo(accountBase.getAccountNo());
            rechargeRequest.setRequestNo(requestNo);
            rechargeRequest.setAmount(rechargeDubboRequestDTO.getAmount());
            rechargeRequest.setExpectPayCompany(PayCompanyEnum.enumOf(rechargeDubboRequestDTO.getPayChannelCode()));
            rechargeRequest.setRechargeWay(RechargeWayEnum.SWIFT);
            rechargeRequest.setNiiwooRedirectUrl(rechargeDubboRequestDTO.getRedirectUrl());
            List<TradeConfigEnum> enums = new ArrayList<>();
            enums.add(TradeConfigEnum.LANMAO_PAGE_EXPIRE_MIN);
            //查询交易配置，获取懒猫页面过期时间
            Map<String, String> configMap = tradeConfigDubboService.selectTradeConfigByEmuns(enums);
            String expireMinStr = configMap.get(TradeConfigEnum.LANMAO_PAGE_EXPIRE_MIN.getConfigKey());
            Integer expireMin = StringUtils.isEmpty(expireMinStr) ? defaultExpireMin : Integer.valueOf(expireMinStr);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Calendar ca = Calendar.getInstance();
            ca.setTime(new Date());
            ca.add(Calendar.MINUTE, expireMin);
            //设置页面过期时间
            rechargeRequest.setExpired(sdf.parse(sdf.format(ca.getTime())));
            rechargeRequest.setRechargeWay(RechargeWayEnum.SWIFT);
            rechargeRequest.setPayType(WebBankTypeEnum.B2C);
            rechargeRequest.setBankcode(rechargeDubboRequestDTO.getBankCode());
//            rechargeRequest.setCallbackMode("DIRECT_CALLBACK");
            //查询用户手机号给后台冗余
            UserBasicInfoResponseDTO userBasicInfoResponseDTO = userBasicInfoDubboService.getUserBasicInfo(rechargeDubboRequestDTO.getUserId());
            String mobile = null;
            String realName = null;
            if (userBasicInfoResponseDTO != null) {
                mobile = userBasicInfoResponseDTO.getMobileNo();
            }
            UserIdentityInfoResponseDTO userIdentityInfoResponseDTO = userIdentityDubboService.get(rechargeDubboRequestDTO.getUserId());
            if (userIdentityInfoResponseDTO != null) {
                realName = userIdentityInfoResponseDTO.getName();
            }

            try {
                //生成充值订单
                rechargeLocalService.initRechargeOrder(rechargeRequest, rechargeDubboRequestDTO.getUserId(), rechargeDubboRequestDTO.getBusinessType(), mobile, realName, sdf.parse(sdf.format(ca.getTime())));
                //请求存管组件
                logger.info("充值请求参数封装{}", JSONObject.toJSONString(rechargeRequest));
                LanMaoGatewayDTO lanMaoGatewayDTO = lanMaoGatewayService.recharge(rechargeRequest);
                rechargeResponseDTO = new RechargeResponseDTO();
                rechargeResponseDTO.setAction(lanMaoGatewayDTO.getAction());
                rechargeResponseDTO.setParams(lanMaoGatewayDTO.getParams());
                logger.info("充值表单参数封装{}", JSONObject.toJSONString(rechargeResponseDTO));
                return rechargeResponseDTO;
            } catch (Exception ex) {
                logger.info("充值请求存管组件异常{}", ex);
            }
        } else {
            throw new BizException("ACC40006");
        }
        return rechargeResponseDTO;
    }

    /**
     * 更新订单状态
     *
     * @param updateRechargeRequestDTO
     */
    @Override
    public UpdateRechargeResponseDTO updateRecharge(UpdateRechargeRequestDTO updateRechargeRequestDTO) {
        //更新订单状态并更新余额
        logger.info("更新订单状态并更新余额updateRecharge" + updateRechargeRequestDTO.getRequestNo());
        if (RechargeWayEnum.PROXY.name().equals(updateRechargeRequestDTO.getRechargeWayEnum()) || RechargeWayEnum.PROTOCOL.name().equals(updateRechargeRequestDTO.getRechargeWayEnum())){
            logger.info("协议+代扣回调：{}",JSON.toJSONString(updateRechargeRequestDTO));
            withholdFacade.processWithholdAsyncNotify(updateRechargeRequestDTO);
            return new UpdateRechargeResponseDTO();
        }

        UpdateRechargeResponseDTO updateRechargeResponseDTO = rechargeLocalService.updateRechargeOrder(updateRechargeRequestDTO);
        //网银充值
        if (RechargeWayEnum.WEB.toString().equals(updateRechargeRequestDTO.getRechargeWayEnum())) {
            return updateRechargeResponseDTO;
        }
        logger.info("充值成功跳转到app需要的参数封装updateRecharge{}", updateRechargeRequestDTO.getRequestNo());

        UserBankInfoResponseDTO userBankInfoResponseDTO;
        AccountBaseResponse accountBaseResponse = accountDubboService.loadAccountByAccountNo(updateRechargeRequestDTO.getAccountNo());
        if(OrgConstant.NIIWOO_ORG_ID.equals(accountBaseResponse.getOrgId())){
            userBankInfoResponseDTO = queryUserBankInfo(updateRechargeResponseDTO.getUserId());
        }else{
            userBankInfoResponseDTO = queryUserBankInfoWithOrgId(updateRechargeResponseDTO.getUserId(),accountBaseResponse.getOrgId());
        }

        if (userBankInfoResponseDTO != null) {
            updateRechargeResponseDTO.setEndNum(userBankInfoResponseDTO.getEndNum());
            updateRechargeResponseDTO.setBankName(userBankInfoResponseDTO.getBankCardType());
        }
        return updateRechargeResponseDTO;
    }

    @Override
    public PageResponseDTO<RechargeRecordResponseDTO> rechargeRecordList(RechargeRecordRequestDTO rechargeRecordRequestDTO) {
        return rechargeLocalService.rechargeRecordList(rechargeRecordRequestDTO);
    }

    @Override
    public List<AccountAmountDTO> queryUserAccountInfo(String userId) {
        return queryUserAccountInfoWithOrgId(userId,OrgConstant.NIIWOO_ORG_ID);
    }

    @Override
    public List<AccountAmountDTO> queryUserAccountInfoWithOrgId(String userId,String orgId) {
        List<AccountAmountDTO> amountDTOList = accountBalanceLocalService.queryAccountAmountWithOrgId(userId,orgId);
        logger.info("账户排序前{}", JSONObject.toJSONString(amountDTOList));
        Collections.sort(amountDTOList);
        logger.info("账户排序后{}", JSONObject.toJSONString(amountDTOList));
        return amountDTOList;
    }

    @Override
    public UserBankInfoResponseDTO queryUserBankInfo(String userId) {
        return queryUserBankInfoWithOrgId(userId,OrgConstant.NIIWOO_ORG_ID);
    }

    @Override
    public UserBankInfoResponseDTO queryUserBankInfoWithOrgId(String userId,String orgId) {
        logger.info("查询用户银行卡信息{}", userId);
        Assert.notNull(userId, "用户银行卡信息 build UserBankInfoResponseDTO userId is null.");
        //查询用户银行卡
        BankCard bankCard;
        if(OrgConstant.NIIWOO_ORG_ID.equals(orgId)){
            bankCard = bankCardService.getSimpleUserBankCard(userId);
        }else{
            AccountBaseResponse accountBaseResponse = accountDubboService.loadOrgAccount(userId,orgId);
            bankCard = bankCardService.getOrgUserBankCard(accountBaseResponse.getAccountId());
        }

        if (bankCard == null) {
            throw new BizException("ACC10012");
        }
        //查询用户银行卡对应的银行的限额信息 todo
        PayChannelDTO payChannelDTO = bankCardDubboService.getUserRechargeChannelByRoute(bankCard.getBankTypeId(), userId);
        BankType bankType = bankTypeService.queryBankTypeById(bankCard.getBankTypeId());
        String bankAccountNo = bankCard.getBankAccountNo();
        bankAccountNo = privacyMasks.decryptPrivacy(bankAccountNo);
        UserBankInfoResponseDTO userBankInfoResponseDTO = new UserBankInfoResponseDTO();
        if (bankType != null) {
            userBankInfoResponseDTO.setBankCardType(bankType.getBankName());
        }
        userBankInfoResponseDTO.setBankCode(bankCard.getBankCode());
        userBankInfoResponseDTO.setEachLimitAmount(payChannelDTO.getMaxAmountPerTrade());
        userBankInfoResponseDTO.setEndNum(bankAccountNo.substring(bankAccountNo.length() - 4, bankAccountNo.length()));
        userBankInfoResponseDTO.setMonthlyLimitAmount(payChannelDTO.getMaxAmountPerMonth());
        userBankInfoResponseDTO.setPayChannelCode(payChannelDTO.getPayChannelCode());
        return userBankInfoResponseDTO;
    }

    @Override
    public void queryOrderByStatusUpdate() {
        logger.info("查询订单并且更新状态queryOrderByStatusUpdate");
        //查询在处理中的标的，查询在处理中的标的，大于5分钟小于2天
        List<RechargeUpdateResponseDTO> responseDTOS = rechargeLocalService.queryOrderByStatus();
        if (!responseDTOS.isEmpty()) {
            responseDTOS.forEach(o -> {
                try {
                //先去存管查该订单
                QueryTransactionRequest request = new QueryTransactionRequest();
                request.setTransactionType(TradeQueryTypeEnum.RECHARGE);
                request.setPlatformUserNo(o.getAccountNo());
                request.setRequestNo(o.getRequestNo());
                CompletableFuture<QueryRechargeResponse> responseCompletableFuture = lanMaoDirectService.queryRecharge(request);
                    logger.info("充值查询结果：" + JSON.toJSONString(responseCompletableFuture.get()));
                    QueryRechargeResponse response = responseCompletableFuture.get();
                    Byte code = response.getCode();
                    //请求成功，掉单情况
                    if (ResponseCodeEnum.SUCCESS.getValue().equals(code) && ResponseStatusEnum.SUCCESS.getValue().equals(response.getStatus())) {
                        rechargeLocalService.updateOrder(response, o);
                    }

                    //超时情况
                    if (LanMaoErrorCodeEnum.QUERY_OBJECT_NOT_EXIST.getCode().equals(response.getErrorCode())) {
                        Date now = new Date();
                        if (o.getExpiredTime().before(now)) {
                            //关闭充值订单
                            rechargeLocalService.updateRechargeOrder(o.getRequestNo());
                        }
                    }
                } catch (Exception ex) {
                    logger.error("充值订单补偿RechargeDubboServiceImpl--queryOrderByStatusUpdate" + ex);
                }

            });
        }
    }

    @Override
    public RechargeOrderDTO userRechrageSuccRecord(String userId) {
        return userRechrageSuccRecordWithOrgId(userId,OrgConstant.NIIWOO_ORG_ID);
    }

    @Override
    public RechargeOrderDTO userRechrageSuccRecordWithOrgId(String userId,String orgId) {
        return rechargeLocalService.userRechrageSuccRecordWithOrgId(userId,orgId);
    }

    @Override
    public RechargeResponseDTO platformRecharge(RechargeDubboRequestDTO rechargeDubboRequestDTO) {
        /*
         * record by zengshuiqing: 该服务目前仅支持：机构（合作机构、企业借款人）、集团账户网关充值
         * 不支持机构个人账户充值，若以后需要兼容机构个人账户充值，需要在DTO中增加机构id
         */
        logger.info("platformRecharge封装充值的请求参数{}", JSON.toJSONString(rechargeDubboRequestDTO));
        Assert.notNull(rechargeDubboRequestDTO, "platformRecharge封装充值的请求参数 build structureParams rechargeDubboRequestDTO is null.");
        //首先判断用户有没有开通存管账户,判断有没有激活
        AccountCompany accountCompany = accountCompanyService.queryAccountCompanyByOrgId(rechargeDubboRequestDTO.getUserId());
        AccountBaseResponse accountBase;
        BankCard bankCard;
        if (null == accountCompany) {
            if(Strings.isNullOrEmpty(rechargeDubboRequestDTO.getOrgId()) || StringUtils.equals(OrgConstant.NIIWOO_ORG_ID, rechargeDubboRequestDTO.getOrgId())){
                accountBase = accountDubboService.loadNiiwooAccount(rechargeDubboRequestDTO.getUserId(), rechargeDubboRequestDTO.getRole());
                bankCard = bankCardService.getSimpleUserBankCard(rechargeDubboRequestDTO.getUserId());
            }else{
                accountBase = accountDubboService.loadOrgAccount(rechargeDubboRequestDTO.getUserId(), rechargeDubboRequestDTO.getOrgId());
                bankCard = bankCardService.getOrgUserBankCard(accountBase.getAccountId());
            }
        } else {
            accountBase = accountDubboService.loadOrgAccount(accountCompany.getUserId(), accountCompany.getOrgId());
            bankCard = bankCardService.getOrgUserBankCard(accountBase.getAccountId());
        }

        if (bankCard == null) {
            throw new BizException("ACC10012");
        }
        if (accountBase != null) {
            //再进行充值业务参数组装
            RechargeRequest rechargeRequest = new RechargeRequest();
            rechargeRequest.setPlatformUserNo(accountBase.getAccountNo());
            rechargeRequest.setRequestNo(lanMaoSequence.getRequestNo());
            rechargeRequest.setAmount(rechargeDubboRequestDTO.getAmount());
            rechargeRequest.setExpectPayCompany(PayCompanyEnum.enumOf(rechargeDubboRequestDTO.getPayChannelCode()));
            rechargeRequest.setRechargeWay(RechargeWayEnum.WEB);
            rechargeRequest.setNiiwooRedirectUrl(rechargeDubboRequestDTO.getRedirectUrl());
            //默认5分钟过期
            Integer defaultExpireMin = 15;
            List<TradeConfigEnum> enums = new ArrayList<>();
            enums.add(TradeConfigEnum.LANMAO_PAGE_EXPIRE_MIN);
            //查询交易配置，获取懒猫页面过期时间
            Map<String, String> configMap = tradeConfigDubboService.selectTradeConfigByEmuns(enums);
            String expireMinStr = configMap.get(TradeConfigEnum.LANMAO_PAGE_EXPIRE_MIN.getConfigKey());
            Integer expireMin = StringUtils.isEmpty(expireMinStr) ? defaultExpireMin : Integer.valueOf(expireMinStr);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Calendar ca = Calendar.getInstance();
            ca.setTime(new Date());
            ca.add(Calendar.MINUTE, expireMin);
            try {
                rechargeRequest.setExpired(sdf.parse(sdf.format(ca.getTime())));  //设置页面过期时间
            } catch (ParseException e) {
                logger.error("设置页面过期时间转换错误");
                return null;
            }
            String mobile = null;
            String realName = null;

            //平台网银||担保机构
            if (PlatformConstant.PLATFORM_USER_ID.equals(rechargeDubboRequestDTO.getUserId())) {
                mobile = privacyMasks.decryptPrivacy(bankCard.getMobileNo());
                realName = bankCard.getRealName();
            }else if(accountBase.getAccountType().equals(AccountTypeEnum.ENTERPRISE.getValue())){
                SimpleOrgInfo orgInfo = organizationDubboService.getByOrgId(accountBase.getUserId());
                if(orgInfo == null){
                    throw new BizException("ACC17027");
                }
                mobile = privacyMasks.decryptPrivacy(bankCard.getMobileNo());
                realName = orgInfo.getAbbreviation();
            } else {
                //个人网银
                UserBasicInfoResponseDTO userBasicInfoResponseDTO = userBasicInfoDubboService.getUserBasicInfo(rechargeDubboRequestDTO.getUserId());
                if (userBasicInfoResponseDTO != null) {
                    mobile = userBasicInfoResponseDTO.getMobileNo();
                }
                UserIdentityInfoResponseDTO userIdentityInfoResponseDTO = userIdentityDubboService.get(rechargeDubboRequestDTO.getUserId());
                if (userIdentityInfoResponseDTO != null) {
                    realName = userIdentityInfoResponseDTO.getName();
                }
            }
            try {
                //生成充值订单
                rechargeLocalService.initRechargeOrder(rechargeRequest, rechargeDubboRequestDTO.getUserId(), rechargeDubboRequestDTO.getBusinessType(), mobile, realName,sdf.parse(sdf.format(ca.getTime())));
                //请求存管组件
                LanMaoGatewayDTO lanMaoGatewayDTO = lanMaoGatewayService.recharge(rechargeRequest);
                RechargeResponseDTO rechargeResponseDTO = new RechargeResponseDTO();
                rechargeResponseDTO.setAction(lanMaoGatewayDTO.getAction());
                rechargeResponseDTO.setParams(lanMaoGatewayDTO.getParams());
                logger.info("充值请求参数封装参数{}", JSON.toJSONString(rechargeResponseDTO));
                return rechargeResponseDTO;
            } catch (Exception ex) {
                logger.error("时间异常structureParams", ex);
            }
        }
        return null;
    }

    @Override
    public PayChannelDTO queryPayChannelCode() {
        return rechargeLocalService.selectPayChannelCode();
    }

    @Override
    public RechargeOrderDTO queryFirstRechrageSuccessRecord(String userId) {
        return rechargeLocalService.queryFirstRechrageSuccessRecord(userId);
    }

    @Override
    public BigDecimal queryUserTotalRechrageAmount(String userId) {
        return rechargeLocalService.queryUserTotalRechrageAmount(userId);
    }

    @Override
    public BigDecimal queryUserTotalRechrageAmountWithOrgId(String userId,String orgId) {
        return rechargeLocalService.queryUserTotalRechrageAmountWithOrgId(userId,orgId);
    }

	@Override
	public RechargeEnableResponse rechargeEnable(String userId) {
		return rechargeEnableWithOrgId(userId,OrgConstant.NIIWOO_ORG_ID);
	}

    @Override
    public Boolean haveRechargingOrder(Long accountId) {
        return rechargeLocalService.queryRechargingOrderList(accountId).size()>0;
    }

    @Override
    public RechargeEnableResponse rechargeEnableWithOrgId(String userId,String orgId) {
        RechargeEnableResponse dto = new RechargeEnableResponse();
        dto.setRechargeEnable((byte) 1);

        //查询用户银行卡信息
        BankCard bankCard;
        if(OrgConstant.NIIWOO_ORG_ID.equals(orgId)){
            bankCard = bankCardService.getSimpleUserBankCard(userId);
        }else{
            AccountBaseResponse accountBaseResponse = accountDubboService.loadOrgAccount(userId, orgId);
            bankCard = bankCardService.getOrgUserBankCard(accountBaseResponse.getAccountId());
        }

        if (bankCard == null) {
            throw new BizException("ACC10012");
        }

        // 获取当前用户银行卡对应的银行信息
        BankType bankType = bankTypeService.getBankTypeByCode(bankCard.getBankCode());
        if(bankType == null){
            throw new BizException("ACC10013");
        }

        // 判断是否需要充值换绑引导，1-需要
        if (bankType.getRechargeChangeStatus() == 1) {
            dto.setBankCode(bankType.getBankCode());
            dto.setBankName(bankType.getBankName());
            dto.setRechargeEnable((byte) 0); // 不支持充值
            dto.setRebindEnable((byte) 1); // 1 - 可以换绑卡

            //判断是否存在换绑卡的单，如果存在不能换绑卡
            List<Long> accountIds = rechargeLocalService.getAccountIdByUserIdAndOrgId(userId,orgId);
            BankCardRebindOrder rebind = bankCardService.getCurrentRebindOrderWithAccountIds(userId,accountIds);
            if (rebind != null && rebind.getAuditStatus() == 1 && rebind.getDelFlag() == 0) {//审核中未删除
                dto.setRebindEnable((byte) 0);
                dto.setRebindForbidReason((byte) 1); // 1- 存在审核中的换绑卡申请
            }

            //查看是否融360支持
            RebindBankCardCheckResponse rebindCheckResponse = bankCardDubboService.rebindBankCardCheck(userId,orgId);
            if (rebindCheckResponse.getForbidRebind()) {
                if (rebindCheckResponse.getRebindForbidReasonEnum().getValue() == 1) {
                    dto.setRebindEnable((byte) 0);
                    dto.setRebindForbidReason((byte) 2); // 2- 其他
                }
            }
        }

        return dto;
    }

    @Override
    public RechargeStatisticsResponseDTO statisticsCurrentRecharge(String userId,String orgId){
        return rechargeLocalService.statisticsRecharge(userId,orgId);
    }

    @Override
    public RechargeAccountTypeDTO queryLatelyRechargeAccountType(RechargeAccountTypeRequestDTO rechargeAccountTypeRequestDTO){
        RechargeAccountTypeDTO rechargeAccountTypeDTO = new RechargeAccountTypeDTO();
        RechargeOrder rechargeOrder = rechargeLocalService.queryLatelyRechargeAccountType(rechargeAccountTypeRequestDTO);
        if( null == rechargeOrder ){
            return null;
        }
        rechargeAccountTypeDTO.setAccountId(rechargeOrder.getAccountId());
        rechargeAccountTypeDTO.setAccountRole(rechargeOrder.getAccountRole());
        return rechargeAccountTypeDTO;
    }

    @Override
    public RechargeMoneyVerifyResponseDTO getStatisticsRechargeMoneyByUserId(RechargeAccountTypeRequestDTO rechargeAccountTypeRequestDTO){
        return rechargeLocalService.getStatisticsRechargeMoneyByUserId(rechargeAccountTypeRequestDTO);
    }

    @Override
    public BankInfoRespDTO getBankInfoByOrderId(Long orderId){
        return rechargeLocalService.getBankInfoByOrderId(orderId);
    }

    public RechargeQueryResponseDTO queryRechargeCompensation(Long orderId){
        if (!HintManagerHolder.isMasterRouteOnly()) {
            HintManagerHolder.clear();
            HintManager hintManager = HintManager.getInstance();
            hintManager.setMasterRouteOnly();
        }
        RechargeQueryResponseDTO rechargeQueryResponseDTO = new RechargeQueryResponseDTO();
        RechargeOrderDTO orderDTO = rechargeLocalService.queryOrderByOrderId(orderId);
        AccountBaseResponse accountBaseResponse =  accountDubboService.loadAccountById(orderDTO.getAccountId());
        try {
            //先去存管查该订单
            QueryTransactionRequest request = new QueryTransactionRequest();
            request.setTransactionType(TradeQueryTypeEnum.RECHARGE);
            request.setPlatformUserNo(accountBaseResponse.getAccountNo());
            request.setRequestNo(orderDTO.getRequestNo());
            CompletableFuture<QueryRechargeResponse> responseCompletableFuture = lanMaoDirectService.queryRecharge(request);
            logger.info("充值查询结果：" + JSON.toJSONString(responseCompletableFuture.get()));
            QueryRechargeResponse response = responseCompletableFuture.get();
            Byte code = response.getCode();

            //请求成功，掉单情况
            if (ResponseCodeEnum.SUCCESS.getValue().equals(code) && ResponseStatusEnum.SUCCESS.getValue().equals(response.getStatus())) {
                String rechargeStatus = response.getRecords().get(0).getStatus();
                if("SUCCESS".equals(rechargeStatus)) {
                    RechargeUpdateResponseDTO rechargeUpdateResponseDTO = new RechargeUpdateResponseDTO();
                    rechargeUpdateResponseDTO.setAccountId(orderDTO.getAccountId());
                    rechargeUpdateResponseDTO.setAccountNo(accountBaseResponse.getAccountNo());
                    rechargeUpdateResponseDTO.setAmount(orderDTO.getAmount());
                    rechargeUpdateResponseDTO.setExpiredTime(orderDTO.getExpiredTime());
                    rechargeUpdateResponseDTO.setId(orderDTO.getId());
                    rechargeUpdateResponseDTO.setRequestNo(orderDTO.getRequestNo());
                    rechargeUpdateResponseDTO.setStatus(orderDTO.getStatus());
                    rechargeUpdateResponseDTO.setUserId(orderDTO.getUserId());
                    rechargeLocalService.updateOrder(response, rechargeUpdateResponseDTO);
                    orderDTO = rechargeLocalService.queryOrderByOrderId(orderId);
                    rechargeQueryResponseDTO.setResult(orderDTO.getStatus());
                    logger.info("充值存管查询订单：{}处理成功",orderId);
                    //return rechargeQueryResponseDTO;
                }else if("PENDDING".equals(rechargeStatus)){
                    rechargeQueryResponseDTO.setResult(orderDTO.getStatus());
                    logger.info("充值存管查询订单：{} 处理中",orderId);
                }else{
                    rechargeQueryResponseDTO.setResult(orderDTO.getStatus());
                    logger.info("充值存管查询订单：{} 充值失败",orderId);
                    // 充值失败暂不处理，交由定时器再次扫描，以防存管系统在非常短的时间状态脏读；
                }
            }else{
                rechargeQueryResponseDTO.setResult(orderDTO.getStatus());
                rechargeQueryResponseDTO.setErrorCode(response.getErrorCode());
                rechargeQueryResponseDTO.setErrorMessage(response.getErrorMessage());
                //rechargeQueryResponseDTO.setChannelErrorCode(response.getC);
            }

        } catch (Exception ex) {
            logger.error("单笔充值订单补偿RechargeDubboServiceImpl--queryRechargeCompensation" + ex);
            rechargeQueryResponseDTO.setResult(orderDTO.getStatus());
        }
        return rechargeQueryResponseDTO;
    }

}
